// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_Line_2.cpp 167 2007-11-02 15:36:54Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Kernel/Py_Line_2.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================
//
#include <CGAL/basic.h>
#include <include/Kernels.h>

#include <boost/python.hpp>
#include <boost/cstdint.hpp>

using namespace boost::python;

const char * Line_2_doc[]={
"An object l of the data type Line_2 is a directed straight line in the two-dimensional Euclidean plane ExE.\nIt is defined by the set of points with Cartesian  coordinates (x,y) that satisfy the equation l : ax + by + c = 0\nThe line splits ExE in a positive and a negative side.\nA point p with Cartesian coordinates (px, py) is on the positive side of l, iff a px + b py + c > 0, it is on the negative side of l, iff a px + b py + c < 0. The positive side is to the left of l.\n\
For more details see a C++ documentation:\n\
http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/Kernel_23_ref/Class_Line_2.html",
"l = Line_2( double a, double b, double c)\nintroduces a line l with the line equation in Cartesian coordinates ax +by +c = 0.\n"\
"l = Line_2( Point_2 p, Point_2 q)\nintroduces a line l passing through the points p and q. Line l is directed from p to q.\n"\
"l = Line_2( Point_2 p, Direction_2 d)\nintroduces a line l passing through point p with direction d.\n"\
"l = Line_2( Point_2 p, Vector_2 v)\nintroduces a line l passing through point p and oriented by v.\n"\
"l = Line_2( Segment_2 s)\nintroduces a line l supporting the segment s, oriented from source to target.\n"\
"l = Line_2( Ray_2 r)\nintroduces a line l supporting the ray r, with same orientation.\n",
"a(self) -> returns the first coefficient of l.\n",
"b(self) -> returns the second coefficient of l.\n",
"c(self) -> returns the third coefficient of l.\n",
"transform(self,Aff_transformation_2 t) -> Line_2\nreturns the line obtained by applying t on a point on l and the direction of l.\n",
"opposite(self) -> Line_2\nreturns the line with opposite direction.\n",
"direction(self) -> Line_2\nreturns the direction of l.\n",
"to_vector(self) -> Vector_2\n returns a vector having the direction of l.\n",
"perpendicular(self,Point_2 p) -> Line_2\nreturns the line perpendicular to l and passing through p,\nwhere the direction is the direction of l rotated counterclockwise by 90 degrees.\n",
"projection(self,Point_2 p) -> Point_2\nreturns the orthogonal projection of p onto l.\n",
"is_degenerate(self) ->bool\nline l is degenerate, if the coefficients a and b of the line equation are zero.\n",
"oriented_side(self, Point_2 p) -> Oriented_side\nreturns ON_ORIENTED_BOUNDARY, ON_NEGATIVE_SIDE, or the constant ON_POSITIVE_SIDE, depending on the position of p relative to the oriented line l.\n",
"x_at_y(self,y) -> returns the x-coordinate of the point at l with given y-coordinate.\nPrecondition: l is not horizontal.",
"y_at_x(self,x) -> returns the y-coordinate of the point at l with given x-coordinate.\nPrecondition: l is not vertical.",
"point(self,i) -> Point_2\nreturns an arbitrary point on l.\nIt holds point(i) == point(j), iff i==j.\nFurthermore, l is directed from point(i)  to point(j), for all i < j."
};

template<class Line_2>
boost::python::str py_repr_Line_2(const Line_2& l )
{
	using namespace boost::python;
	return str("Line_2("+ str(l.a()) +" x + "+ str(l.b()) +" y + "+ str(l.c()) +" = 0.0)" );
}

template<class kernel>
void Py_Line_2()
{
	typedef typename kernel::Point_2 							Point_2;
	typedef typename kernel::Segment_2 							Segment_2;
 	typedef typename kernel::Vector_2 							Vector_2;
 	typedef typename kernel::Direction_2 						Direction_2;
 	typedef typename kernel::Line_2 						    Line_2;
  	typedef typename kernel::Ray_2 						        Ray_2;
	typedef typename kernel::FT 								FT;
	typedef typename kernel::RT									RT;

    class_< Line_2 >("Line_2",Line_2_doc[0], init<  >())
        .def(init< const Line_2& >(Line_2_doc[1]))
        .def(init< const Point_2&, const Point_2& >())
        .def(init< const FT&, const FT&, const FT& >())
        .def(init< const double&, const double&, const double& >())
        .def(init< const Segment_2& >())
        .def(init< const Ray_2& >())
        .def(init< const Point_2&, const Direction_2& >())
        .def(init< const Point_2&, const Vector_2& >())
        .def("a", &Line_2::a,Line_2_doc[2])
        .def("b", &Line_2::b,Line_2_doc[3])
        .def("c", &Line_2::c,Line_2_doc[4])
        .def("transform", &Line_2::transform,Line_2_doc[5])
        .def("opposite", &Line_2::opposite,Line_2_doc[6])
        .def("direction", &Line_2::direction,Line_2_doc[7])
        .def("to_vector", &Line_2::to_vector,Line_2_doc[8])
        .def("perpendicular", &Line_2::perpendicular,Line_2_doc[9])
        .def("projection", &Line_2::projection,Line_2_doc[10])
        .def("is_horizontal", &Line_2::is_horizontal)
        .def("is_vertical", &Line_2::is_vertical)
        .def("is_degenerate", &Line_2::is_degenerate,Line_2_doc[11])
        .def("oriented_side", &Line_2::oriented_side,Line_2_doc[12])
        .def("has_on_boundary", &Line_2::has_on_boundary)
        .def("has_on_positive_side", &Line_2::has_on_positive_side)
        .def("has_on_negative_side", &Line_2::has_on_negative_side)
	.def("__repr__",&py_repr_Line_2<Line_2>)
        .def("has_on", &Line_2::has_on)
        .def("x_at_y", &Line_2::x_at_y,Line_2_doc[13])
        .def("y_at_x", &Line_2::y_at_x,Line_2_doc[14])
        .def("point", (Point_2 (Line_2::*)() const)&Line_2::point)
        .def("point", (Point_2 (Line_2::*)(int) const)&Line_2::point,Line_2_doc[15])
        .def( self == self )
        .def( self != self )
    ;
}

void export_Line_2()
{
	Py_Line_2<K>();
}
